package com.pj.service.impl;

import com.pj.ThreadUtils;
import com.pj.entity.Book;
import com.pj.utils.CrawlParser;
import com.pj.entity.CrawRuleBean;
import com.pj.entity.CrawlSource;
import com.pj.mapper.CrawMapper;
import com.pj.redis.RedisUtils;
import com.pj.service.CrawlService;
import com.pj.utils.RestTemplateUtils;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;


import javax.annotation.Resource;
import java.util.*;

/**
 * @author: szy
 * @program: pj-novel
 * @description: 爬虫服务实现类
 * @create: 2022-09-19 11:09
 **/
@Service
public class CrawlServiceImpl implements CrawlService {
    @Autowired
    CrawlService crawlService;

    @Autowired
    ThreadUtils threadUtils;

    @Autowired
    CrawMapper crawServiceMapper;

    @Autowired
    RabbitTemplate rabbitTemplate;





    private static RestTemplate restTemplate = RestTemplateUtils.getInstance("utf-8");
    private static final Logger logger = LoggerFactory.getLogger(CrawlServiceImpl.class);

    @SneakyThrows
    @Override
    public void openOrCloseCrawl(Integer sourceId, Byte sourceStatus) {


//        //判断是开启还是关闭，如果是关闭，则修改数据库状态后获取该爬虫正在运行的线程集合并全部停止
//        //如果是开启，先查询数据库中状态，判断该爬虫源是否还在运行，如果在运行，则忽略，
//        // 如果没有则修改数据库状态，并启动线程爬取小说数据加入到runningCrawlThread中
//        if (sourceStatus == (byte) 0) {
//            //关闭,直接修改数据库状态，并直接修改数据库状态后获取该爬虫正在运行的线程集合全部停止
//            crawlService.updateCrawlSourceStatus(sourceId, sourceStatus);
//            Set<Long> runningCrawlThreadId = (Set<Long>) redisUtils.getValue("runningCrawlTread" + sourceId);
//            if (runningCrawlThreadId != null) {
//                for (Long ThreadId : runningCrawlThreadId) {
//                    Thread thread = ThreadUtils.findThread(ThreadId);
//                    if (thread != null && thread.isAlive()) {
//                        thread.interrupt();
//                    }
//                }
//            }
//        } else {
//            //开启
//            //查询爬虫源状态和规则
//            CrawlSource source = crawServiceMapper.queryCrawlSource(sourceId);// 查询数据库
//            int realSourceStatus = source.getSourceStatus();
//
//            if (realSourceStatus == 0) {
//                //该爬虫源已经停止运行了,修改数据库状态，并启动线程爬取小说数据加入到runningCrawlThread中
//                crawlService.updateCrawlSourceStatus(sourceId, sourceStatus);
//                CrawRuleBean ruleBean = new ObjectMapper().readValue(source.getCrawlRule(), CrawRuleBean.class);
//
//                Set<Long> threadIds = new HashSet<>();
//                //按分类开始爬虫解析任务
//                for (int i = 0; i < 10; i++) {
//                    final int catId = i;
//                    Thread thread = new Thread(() -> CrawlServiceImpl.this.parseBookList(catId, ruleBean, sourceId));
//                    thread.start();
//                    //thread加入到监控缓存中
//                    threadIds.add(thread.getId());
//
//                }
//                redisUtils.setCacheObject("runningCrawlTread" + sourceId, threadIds);
//
//
//            }
//
//
//        }

    }

    /**
     * @param sourceId
     * @param sourceStatus
     */

    @Override
    public void updateCrawlSourceStatus(Integer sourceId, Byte sourceStatus) {

    }





//    @Override
//    public void parseBookList(int catId, CrawRuleBean ruleBean, Integer sourceId) {

        //当前页码1
//        int page = 1;
//        int totalPage = page;
//
//        while (page <= totalPage) {
//
//            try {
//
//                if (StringUtils.isNotBlank(ruleBean.getCatIdRule().get("catId" + catId))) {
//                    //拼接分类URL
//                    String catBookListUrl = ruleBean.getBookListUrl()
//                            .replace("{catId}", ruleBean.getCatIdRule().get("catId" + catId))
//                            .replace("{page}", page + "");
//
//                    String bookListHtml = getByHttpClientWithChrome(catBookListUrl);
//                    if (bookListHtml != null) {
//                        Pattern bookIdPatten = Pattern.compile(ruleBean.getBookIdPatten());
//                        Matcher bookIdMatcher = bookIdPatten.matcher(bookListHtml);
//                        boolean isFindBookId = bookIdMatcher.find();
//                        while (isFindBookId) {
//                            try {
//                                //1.阻塞过程（使用了 sleep,同步锁的 wait,socket 中的 receiver,accept 等方法时）
//                                //捕获中断异常InterruptedException来退出线程。
//                                //2.非阻塞过程中通过判断中断标志来退出线程。
//                                if (Thread.currentThread().isInterrupted()) {
//                                    return;
//                                }
//
//                                String bookId = bookIdMatcher.group(1);
//                                //爬虫结果入库
//                                parseBookAndSave(catId, ruleBean, sourceId, bookId);
//                            } catch (Exception e) {
//                                logger.error(e.getMessage(), e);
//                            }
//
//                            isFindBookId = bookIdMatcher.find();
//                        }
//
//                        Pattern totalPagePatten = Pattern.compile(ruleBean.getTotalPagePatten());
//                        Matcher totalPageMatcher = totalPagePatten.matcher(bookListHtml);
//                        boolean isFindTotalPage = totalPageMatcher.find();
//                        if (isFindTotalPage) {
//
//                            totalPage = Integer.parseInt(totalPageMatcher.group(1));
//
//                        }
//                    }
//                }
//            } catch (Exception e) {
//                logger.error(e.getMessage(), e);
//            }
//
//            page += 1;
//        }
//

//    }

    /**
     * 采集小说并入库
     *
     * @param catId    分类ID
     * @param ruleBean 采集规则
     * @param sourceId 数据源ID
     * @param bookId   小说ID
     * @return
     */
//    @Override
    public boolean parseBookAndSave(int catId, CrawRuleBean ruleBean, Integer sourceId, String bookId) {
//        final AtomicBoolean parseResult = new AtomicBoolean(false);
//
//        CrawlParser.parseBook(ruleBean, bookId, book -> {
//            if (book.getBookName() == null || book.getAuthorName() == null) {
//                return;
//            }
//            //这里只做新书入库，查询是否存在这本书
//            Book existBook = bookService.queryBookByBookNameAndAuthorName(book.getBookName(), book.getAuthorName());
//            //如果该小说不存在，则可以解析入库，但是标记该小说正在入库，30分钟之后才允许再次入库
//            if (existBook == null) {
//                //没有该书，可以入库
//                book.setCatId(catId);
//                //根据分类ID查询分类
//                book.setCatName(bookService.queryCatNameByCatId(catId));
//                if (catId == 7) {
//                    //女频
//                    book.setWorkDirection(1);
//                } else {
//                    //男频
//                    book.setWorkDirection(0);
//                }
//                book.setCrawlBookId(bookId);
//                book.setCrawlSourceId(sourceId);
//                book.setCrawlLastTime(new Date());
//                book.setId(Long.parseLong(UUID.randomUUID().toString()));
//
//                //解析章节目录
//                boolean parseIndexContentResult = CrawlParser.parseBookIndexAndContent(bookId, book, ruleBean, new HashMap<>(0), chapter -> {
//                    bookService.saveBookAndIndexAndContent(book, chapter.getBookIndexList(), chapter.getBookContentList());
//                });
//                parseResult.set(parseIndexContentResult);
//            } else {
//                //只更新书籍的爬虫相关字段
//                bookService.updateCrawlProperties(existBook.getId(), sourceId, bookId);
//                parseResult.set(true);
//            }
//        });
//
//        return parseResult.get();
        return false;
    }

    /**
     * 开始爬虫
     *
     * @return
     */
    @Override
    public boolean startCloseCrawl(Integer sourceId) {
        /*
        1.  根据sourceId  查询数据库,获取数据源和爬虫路径
        1.  发送笔趣阁类型请求,获取当前分类下的书籍目录
        2.  解析数据目录html,获取目录中的封面和书籍链接
        3.  根据书籍发送请求获取书籍目录页面
        4.  根据数据目录页面获取书名,作者,状态,更新时间,内容简介,章节目录链接和章节目录名
        5.  根据目录名, 获取章节内容
        6.  爬虫结果,状态等入库
        PS: 书籍目录使用多线程,并且为了防止反爬虫,线程之间睡5s, 由于服务器压力,所以数据只爬链接首页,没有爬取其他分页的
            如果爬取分页的,爬取路径需要采取发送分页请求,https://www.bqg99.com/json?sortid=1&page=4
            sortid为分类id,如:玄幻sortid=1
        */
        CrawlSource crawSource = crawServiceMapper.getCrawSource(sourceId);
        String crawlRuleUrl = crawSource.getCrawlRule();
        String crawlRuleChilds = crawSource.getCrawlRuleChild();
        List<String> crawlRuleChildList = Arrays.asList(crawlRuleChilds.split(","));
        for (String catalogue : crawlRuleChildList) {
          String catalogueUrl = crawlRuleUrl+catalogue;
            List<Book> categoryBookList = CrawlParser.getByHttpClientWithChrome(catalogueUrl, catalogue, sourceId);
        }
        return false;
    }

    @Override
    public boolean openCloseCrawl(Integer sourceId) {
        rabbitTemplate.convertAndSend("chaptersDetail_url","http:啦啦啦~");
        return false;
    }


}
